/*
 * name:scrollBar
 * vertion: v1.3.2
 * update: 没有合法dom不执行，防止报错
 * date: 2014-12-02
 */
define(function(require, exports, module) {
    var $ = require('jquery');
    var base = require('base');
    require('./scroll-bar.css')

    var isFirefox = typeof document.body.style.MozUserSelect != 'undefined',
        addEvent = function(obj, type, fn) {
            if (obj.addEventListener) {
                obj.addEventListener(isFirefox ? 'DOMMouseScroll' : type, fn, false)
            } else {
                obj.attachEvent('on' + type, fn)
            };
            return fn
        },
        delEvent = function(obj, type, fn) {
            if (obj.removeEventListener) {
                obj.removeEventListener(isFirefox ? 'DOMMouseScroll' : type, fn, false)
            } else {
                obj.detachEvent('on' + type, fn)
            }
        };

    $.fn.scrollBar = function(config) {
        var $this = $(this),
            scrollCont, sliderBar, sliderLength, prop, wheelHandler, init, passive, setSlider,
            _length, _breadth, _posiLength, _posiBreadth, thisLength,
            sliderGone = 0,
            testVal = false,
            sliderBar = $("<div class='scroll_bar' onselectstart='return false;'>\
            			<div class='scroll_up'><!----></div>\
            			<div class='scroll_slider' unselectable='on'><!----></div>\
            			<div class='scroll_down'><!----></div>\
            		</div>"),
            btnUp = sliderBar.children('.scroll_up'),
            btnDown = sliderBar.children('.scroll_down'),
            scrollSlider = sliderBar.children('.scroll_slider'),
            opts = {
                wrap: null,				//包裹元素，默认不指定，将新增div.scroll_c
                monitor: false,			//是否监听内容变化（用于多插件协作），布尔值，默认false
                overflow: "y",			//滚动条方向，默认"y"(纵向)，可选"x"(横向)
                keyway: 30,				//按钮键程，默认30（px）
                width: 10,				//滚动条宽度，默认10（px）
                btnLength: 0,			//按钮长度，默认0（不显示按钮）
                btnBreadth: '100%',		//按钮宽度，默认与滚动条同宽
                sliderWidth: '100%'		//滑块宽度，默认与滚动条同宽
            };
        if(!$this.length) return;
        $.extend(opts, config || {}, $this.data('config') || {});
        if (base.getType() != "Pc") {
            $this.css({
                'overflow': 'auto',
                '-webkit-overflow-scrolling': 'touch'
            });
            return $this;
        };
        if ($(opts.wrap).length) {
            scrollCont = $(opts.wrap)
        } else {
            $this.wrapInner("<div class='scroll_c'></div>");
            scrollCont = $this.children('.scroll_c');
        };
        $this.append(sliderBar);
        //预处理
        switch (opts.overflow) {
            case 'x':
                _length = "width"
                _breadth = "height"
                _posiLength = "left"
                _posiBreadth = "bottom"
                break;
            default:
                _length = "height"
                _breadth = "width"
                _posiLength = "top"
                _posiBreadth = "right"
        };
        thisLength = parseFloat($this.css(_length));
        sliderBar.
        css(_length, "100%").
        css(_breadth, opts.width).
        css(_posiBreadth, 0).
        css(_posiLength, 0);
        btnUp.
        css(_length, opts.btnLength).
        css(_breadth, opts.btnBreadth);
        btnDown.
        css(_length, opts.btnLength).
        css(_breadth, opts.btnBreadth);
        scrollSlider.
        css(_breadth, opts.sliderWidth).
        css(_posiBreadth, 0).
        css(_posiLength, 0);

        if (opts.monitor) passive(scrollCont);

        scrollSlider.bind('mousedown', function(e) {
            var pageLength, topCur, Move;
            if (opts.overflow === 'y') {
                pageLength = e.pageY
            } else {
                pageLength = e.pageX
            };
            topCur = parseFloat($(this)._css(_posiLength));

            $(this).addClass('scroll_slider_on');
            $(document).mousemove(function(e2) {
                if (opts.overflow === 'y') {
                    Move = e2.pageY - pageLength;
                } else {
                    Move = e2.pageX - pageLength;
                };

                sliderGone = topCur + Move;

                setSlider();
                return false;
            });
            $(document).mouseup(function() {
                $(this).unbind();
                scrollSlider.removeClass('scroll_slider_on');
            });
        });
        btnUp.bind({
            'mousedown': function() {
                $(this).addClass('scroll_up_on');
            },
            'mouseup': function() {
                sliderGone = sliderGone - opts.keyway / prop;
                setSlider();
                $(this).removeClass('scroll_up_on');
            }
        });
        btnDown.bind({
            'mousedown': function() {
                $(this).addClass('scroll_down_on');
            },
            'mouseup': function() {
                sliderGone = sliderGone + opts.keyway / prop;
                setSlider();
                $(this).removeClass('scroll_down_on')
            }
        });
        setSlider = function() {
            if (sliderGone < opts.btnLength) {
                sliderGone = opts.btnLength
            } else if (sliderGone > thisLength - opts.btnLength - sliderLength) {
                sliderGone = thisLength - opts.btnLength - sliderLength
            };
            scrollSlider._css(_posiLength, sliderGone)

            scrollCont._css(_posiLength, -((sliderGone - opts.btnLength) * prop))
        };
        init = function(fromMonitor) {
            var _scrollContClone, _scrollContLength;
            if (scrollCont.data(_length)) {
                _scrollContLength = scrollCont.data(_length);
            } else {
                _scrollContClone = scrollCont.clone().css('position', 'absolute').appendTo('body');
                _scrollContLength = parseFloat(_scrollContClone.css(_length));
                scrollCont.css(_length, _scrollContLength).data(_length, _scrollContLength);
            };

            if (_scrollContLength > thisLength) {
                sliderBar.show();
                testVal = true
            } else {
                sliderBar.hide();
                testVal = false
            };
            if (fromMonitor && !testVal) return;
            sliderLength = parseFloat(scrollSlider.css(_length)) ? scrollSlider.css(_length) :
                Math.round(thisLength / _scrollContLength * 100) / 100 * thisLength;

            scrollSlider.css(_length, sliderLength);
            prop = (_scrollContLength - thisLength) < 0 ? 0 :
                (_scrollContLength - thisLength) / (thisLength - opts.btnLength * 2 - sliderLength);

            setSlider();
            //滚轮事件
            wheelHandler = addEvent($this.get(0), 'mousewheel', function(e) {
                e = e || event;
                if (_scrollContLength > thisLength) {
                    var delta = e.wheelDelta ? e.wheelDelta / 3 : -e.detail * 10;
                    e.preventDefault ? e.preventDefault() : (e.returnValue = false);
                    sliderGone -= delta;
                    setSlider();
                } else {
                    sliderGone = 0;
                    setSlider();
                    if (!testVal) {
                        delEvent($this.get(0), 'mousewheel', wheelHandler);
                    }
                }
            });
            _scrollContClone.remove();
        };
        //监听
        passive = function(scrollCont) {
            var scTop, _sliderGone, _ssH = _scrollContLength;
            setInterval(function(event) {
                _sliderGone = parseFloat(scrollCont.css(_length));
                if (scTop != _sliderGone) {
                    //内容定位驱动滑条定位
                    scrollSlider._css(_posiBreadth, opts.btnLength - _sliderGone / prop);
                    scTop = _sliderGone;
                };
                if (scrollCont.css(_length) != _ssH) {
                    init(true);
                    //区分来自监听的初始化
                    _ssH = scrollCont.css(_length)
                }
            }, 16)
        };
        //初始化
        if (scrollCont.find('img').length) {
            require.async('img-loaded', function() {
                scrollCont.imagesLoaded(function() {
                    init(false);
                })
            })
        } else {
            init(false);
        };

        return $this;
    };

})
